package com.bakend.common.config.security;

import com.bakend.common.config.security.handler.CustomerAccessDeniedHandler;
import com.bakend.common.config.security.jwt.JwtFilter;
import com.bakend.common.config.security.login.CustomerUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.CorsFilter;

/**
 * https://blog.csdn.net/zzzgd_666/article/details/96444829
 * https://www.cnblogs.com/wuzhenzhao/p/11103043.html
 * https://blog.csdn.net/yingwang9/article/details/83176195?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242
 */
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private AuthenticationSuccessHandler successHandler;
    @Autowired
    private AuthenticationFailureHandler failureHandler;

    @Autowired
    private CustomerAccessDeniedHandler accessDeniedHandler;
    @Autowired
    private LogoutSuccessHandler logoutSuccessHandler;
    @Autowired
    private AuthenticationEntryPoint authenticationEntryPoint;
    @Autowired
    private CustomerUserDetailService userDetailsService;

//    @Autowired
//    private CorsFilter corsFilter;

    @Autowired
    private JwtFilter jwtFilter;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //todo token失效的问题：主动退出后，token怎么失效处理，多端登录后，旧的token怎么失效
        http.csrf().disable()

                .cors()

                .and()
                .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint)//未登录访问
                .accessDeniedHandler(accessDeniedHandler)//登录后权限不够

                .and()
                .logout()
                .logoutSuccessHandler(logoutSuccessHandler)//主动退出的处理方法

                .and()
                .formLogin()
                .permitAll()
//                .loginProcessingUrl("/login")
//                .usernameParameter("userName")
//                .passwordParameter("pwd")
                .successHandler(successHandler)//登录成功
                .failureHandler(failureHandler)//登录失败

                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)//无状态，不会创建session

                .and()
                .authorizeRequests() // 对请求授权
                .antMatchers("/login","/test")
                .permitAll() //允许所有人访问/noAuth
                .anyRequest() // 任何请求
                .authenticated()// 需要身份认证
                ;

        http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);//jwt认证过滤器
//        http.addFilterBefore(corsFilter, JwtFilter.class);//跨域过滤器


    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //默认就是daoProvider，provder是真正进行验证的地方，不同的校验方式有不同的provider（比如验证码，短信，邮箱等等）
//        auth.authenticationProvider(new DaoAuthenticationProvider());
        //设置自定义userService
        auth.userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());
//        auth.authenticationProvider(new UserJoinTimeAuthenticationProvider(userService));
        super.configure(auth);
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        //静态资源放行，这里配置的话，就不会经过上面配置的认证拦截器了
        //也可以指定静态文件的路径
//        web.ignoring().antMatchers("/static/**");
        web.ignoring().antMatchers("*.html","*.js","*.jpg","*.css");
    }
}
